package cn.example.game.db.dao;
import org.artifact.core.db.JedisDao;
import org.artifact.core.lang.StrPlus;
import redis.clients.jedis.Pipeline;
import org.artifact.core.context.bytebuf.IByteBuff;
import org.artifact.core.context.bytebuf.IByteBuffFactory;
import redis.clients.jedis.Jedis;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Set;
import org.artifact.core.lang.IServer;
import java.util.function.BiFunction;
import org.artifact.core.db.BaseBean;
import cn.hutool.core.map.MapUtil;
import java.util.HashMap;
import org.artifact.core.db.BaseDao;
import cn.example.game.db.bean.PlayerMail;
import static cn.hutool.core.util.ObjectUtil.equal;

public abstract class PlayerMailDAO extends JedisDao<PlayerMail>{
	@Override
	protected String getDBName() {
		return "example_game";
	}
	
	@Override
	protected String getTableName() {
		return "t_player_mail";
	}
	
	@Override
	protected Class<PlayerMail> getEntityClass(){
		return PlayerMail.class;
	}
	
	@Override
	protected PlayerMail createEntity() {
		return new PlayerMail() {};
	}

	@Override
	protected String getPKFieldName() {
		return "id";
	}
	
	// 根据主键导出
	public Map<String,Object> exportByPrimaryKey(long id,BiFunction<BaseDao,BaseBean,Object> function){
		return export(findByPrimaryKey(id),function);
	}
	
	public List<Map<String,Object>> exportByPid(long pid,BiFunction<BaseDao,BaseBean,Object> function){
		return export(findByPid(pid),function);
	}
	
	public Map<String,Object> export(PlayerMail playerMail,BiFunction<BaseDao,BaseBean,Object> function){
		Map<String,Object> data = new HashMap<>();
		data.put("self", function.apply(this,playerMail));
		return data;
	}
	
	public List<Map<String,Object>> export(List<PlayerMail> playerMails,BiFunction<BaseDao,BaseBean,Object> function){
		List<Map<String,Object>> data = new ArrayList<>();
		for(PlayerMail playerMail : playerMails){
			data.add(export(playerMail,function));
		}
		return data;
	}


	public PlayerMail _import(Map<String,Object> data,BiFunction<BaseDao,Map,BaseBean> function){
	    PlayerMail playerMail = createEntity();
	    playerMail = (PlayerMail)function.apply(this,MapUtil.get(data,"self",Map.class));

        return playerMail;
    }

    public List<PlayerMail> _import(List<Map<String,Object>> data,BiFunction<BaseDao,Map,BaseBean> function){
        List<PlayerMail> list = new ArrayList<>();
        for(Map<String,Object> map : data){
            list.add(_import(map,function));
        }
        return list;
    }
	
	

	protected String[] getIndexKey(PlayerMail t){
		String[] indexKeys = new String[1];
		indexKeys[0] = StrPlus.b("pid:", t.getPid()).e();
		return indexKeys;
	}
	
	protected void addIndex(Pipeline p,PlayerMail t){
		String[] keys = indexKeys.get(t.pk());
		if(keys == null){
			keys= getIndexKey(t);
		}
		p.sadd(toBytes(getTableName()+":" + keys[0]), toBytes(t.pk()));
	}
	
	protected void removeIndex(Pipeline p,PlayerMail t){
		String[] keys = indexKeys.get(t.pk());
		if(keys == null){
			keys= getIndexKey(t);
		}
		p.srem(toBytes(getTableName()+":" + keys[0]), toBytes(t.pk()));
	}
	

	public List<PlayerMail> findByPid(long pid){
		return resultList(()->{
			List<PlayerMail> list = new ArrayList<>();
			Jedis jedis = getJedis();
			IByteBuffFactory factory = IServer.me().getContext().getByteBuffFactory();
			IByteBuff byteBuff = null;
			try{
				Set<byte[]> primaryKeys = jedis.smembers(toBytes(getTableName() + ":" + StrPlus.b("pid:", pid).e()));
				for(byte[] primaryKey : primaryKeys){
					byte[] data = jedis.hget(toBytes(getTableName()), primaryKey);
					if(data!=null){
						byteBuff = factory.wrap(data);
						Map<Integer, Object> map = byteBuff.readMap();
						if (map != null) {
							list.add(createEntity().read(map));
						}
					}
				}
			} finally {
				jedis.close();
			}
			return list;
		}, t -> {
			return equal(t.getPid(), pid);
		}) ;
	}
	
}